package com.zhixue.learning.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zhixue.base.exception.ZhiXueException;
import com.zhixue.base.model.PageResult;
import com.zhixue.content.model.po.CoursePublish;
import com.zhixue.learning.feignclient.ContentServiceClient;
import com.zhixue.learning.model.dto.MyCourseTableParams;
import com.zhixue.learning.model.dto.ZxChooseCourseDto;
import com.zhixue.learning.model.dto.ZxCourseTablesDto;
import com.zhixue.learning.mapper.ZxChooseCourseMapper;
import com.zhixue.learning.mapper.ZxCourseTablesMapper;
import com.zhixue.learning.model.po.ZxChooseCourse;
import com.zhixue.learning.model.po.ZxCourseTables;
import com.zhixue.learning.service.MyCourseTablesService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @author Dragon
 * @description MyCourseTablesServiceImpl
 * @date 2023/10/22 15:27
 */
@Slf4j
@Service
public class MyCourseTablesServiceImpl implements MyCourseTablesService {

    @Autowired
    ZxChooseCourseMapper zxChooseCourseMapper;

    @Autowired
    ZxCourseTablesMapper zxCourseTablesMapper;

    @Autowired
    ContentServiceClient contentServiceClient;

    @Autowired
    MyCourseTablesService currentproxy;


    /**
     * 添加选课
     * @param userId
     * @param courseId
     * @return
     */
    @Override
    @Transactional
    public ZxChooseCourseDto addChooseCourse(String userId, Long courseId) {
        //选课调用内容管理查询课程的收费规则
        CoursePublish coursePublish=contentServiceClient.getCoursePublish(courseId);
        if(coursePublish==null){
            ZhiXueException.cast("课程不存在");
        }

        String charge=coursePublish.getCharge();
        ZxChooseCourse chooseCourse = null;
        if ("201000".equals(charge)) {
            // 2. 如果是免费课程，向选课记录表、我的课程表添加数据
            log.info("添加免费课程..");
            chooseCourse = currentproxy.addFreeCourse(userId, coursePublish);
            addCourseTables(chooseCourse);
        } else {
            // 3. 如果是收费课程，向选课记录表添加数据
            log.info("添加收费课程");
            chooseCourse = currentproxy.addChargeCourse(userId, coursePublish);
        }

        // 4. 获取学生的学习资格
        ZxCourseTablesDto courseTablesDto = getLearningStatus(userId, courseId);
        // 5. 封装返回值
        ZxChooseCourseDto chooseCourseDto = new ZxChooseCourseDto();
        BeanUtils.copyProperties(chooseCourse, chooseCourseDto);
        chooseCourseDto.setLearnStatus(courseTablesDto.learnStatus);
        return chooseCourseDto;

    }


    /**
     * 添加到我的课程表
     *
     * @param chooseCourse 选课记录
     */
    @Transactional
    public ZxCourseTables addCourseTables(ZxChooseCourse chooseCourse) {
        String status = chooseCourse.getStatus();
        if (!"701001".equals(status)) {
            ZhiXueException.cast("选课未成功，无法添加到课程表");
        }

        ZxCourseTables courseTables = getZxCourseTables(chooseCourse.getUserId(), chooseCourse.getCourseId());
        if (courseTables != null) {
            return courseTables;
        }
        courseTables = new ZxCourseTables();
        BeanUtils.copyProperties(chooseCourse, courseTables);
        courseTables.setChooseCourseId(chooseCourse.getId());
        courseTables.setCourseType(chooseCourse.getOrderType());
        courseTables.setUpdateDate(LocalDateTime.now());
        int insert = zxCourseTablesMapper.insert(courseTables);
        if (insert <= 0) {
            ZhiXueException.cast("添加我的课程表失败");
        }
        return courseTables;
    }

    /**
     * 根据用户id和课程id查询我的课程表中的某一门课程
     * @param userId
     * @param courseId
     * @return
     */
    private ZxCourseTables getZxCourseTables(String userId, Long courseId) {

        return zxCourseTablesMapper.selectOne(new LambdaQueryWrapper<ZxCourseTables>()
                .eq(ZxCourseTables::getUserId, userId)
                .eq(ZxCourseTables::getCourseId, courseId));
    }


    /**
     * 将免费课程添加到选课表
     * @param userId
     * @param coursePublish
     * @return
     */
    @Override
    @Transactional
    public ZxChooseCourse addFreeCourse(String userId, CoursePublish coursePublish){
        // 1. 先判断是否已经存在对应的选课，因为数据库中没有约束，所以可能存在相同数据的选课
        LambdaQueryWrapper<ZxChooseCourse>lambdaQueryWrapper=new LambdaQueryWrapper<ZxChooseCourse>()
                .eq(ZxChooseCourse::getUserId,userId)
                .eq(ZxChooseCourse::getCourseId,coursePublish.getId())
                .eq(ZxChooseCourse::getOrderType,"700001")//免费课程
                .eq(ZxChooseCourse::getStatus,"701001");//选课成功
        // 1.1 由于可能存在多条，所以这里用selectList
        //解决数据库没有约束的方法之一，可以解决，但不完美
        List<ZxChooseCourse> zxChooseCourses = zxChooseCourseMapper.selectList(lambdaQueryWrapper);
        if(!zxChooseCourses.isEmpty()){
            // 1.2 如果已经存在对应的选课数据，返回一条即可
            return zxChooseCourses.get(0);
        }
        // 2. 数据库中不存在数据，添加选课信息，对照着数据库中的属性挨个set即可
        ZxChooseCourse chooseCourse = new ZxChooseCourse();
        chooseCourse.setCourseId(coursePublish.getId());
        chooseCourse.setCourseName(coursePublish.getName());
        chooseCourse.setUserId(userId);
        chooseCourse.setCompanyId(coursePublish.getCompanyId());
        chooseCourse.setOrderType("700001");
        chooseCourse.setCreateDate(LocalDateTime.now());
        chooseCourse.setCoursePrice(coursePublish.getPrice());
        chooseCourse.setValidDays(365);
        chooseCourse.setStatus("701001");
        chooseCourse.setValidtimeStart(LocalDateTime.now());
        chooseCourse.setValidtimeEnd(LocalDateTime.now().plusDays(365));//在当前时间上加上365天
        int insert = zxChooseCourseMapper.insert(chooseCourse);
        if (insert <= 0) {
            ZhiXueException.cast("添加选课记录失败");
        }
        return chooseCourse;


    }


    /**
     * 将付费课程加入到选课表
     * @param userId
     * @param coursePublish
     * @return
     */
    @Override
    @Transactional
    public ZxChooseCourse addChargeCourse(String userId, CoursePublish coursePublish) {
        // 1. 先判断是否已经存在对应的选课，因为数据库中没有约束，所以可能存在相同数据的选课
        LambdaQueryWrapper<ZxChooseCourse>lambdaQueryWrapper=new LambdaQueryWrapper<ZxChooseCourse>()
                .eq(ZxChooseCourse::getUserId,userId)
                .eq(ZxChooseCourse::getCourseId,coursePublish.getId())
                .eq(ZxChooseCourse::getOrderType,"700002")//免费课程
                .eq(ZxChooseCourse::getStatus,"701002");//选课成功
        // 1.1 由于可能存在多条，所以这里用selectList
        List<ZxChooseCourse> zxChooseCourses = zxChooseCourseMapper.selectList(lambdaQueryWrapper);
        if(!zxChooseCourses.isEmpty()){
            // 1.2 如果已经存在对应的选课数据，返回一条即可
            return zxChooseCourses.get(0);
        }
        // 2. 数据库中不存在数据，添加选课信息，对照着数据库中的属性挨个set即可
        ZxChooseCourse chooseCourse = new ZxChooseCourse();
        chooseCourse.setCourseId(coursePublish.getId());
        chooseCourse.setCourseName(coursePublish.getName());
        chooseCourse.setUserId(userId);
        chooseCourse.setCompanyId(coursePublish.getCompanyId());
        chooseCourse.setOrderType("700002");
        chooseCourse.setCreateDate(LocalDateTime.now());
        chooseCourse.setCoursePrice(coursePublish.getPrice());
        chooseCourse.setValidDays(365);
        chooseCourse.setStatus("701002");
        chooseCourse.setValidtimeStart(LocalDateTime.now());
        chooseCourse.setValidtimeEnd(LocalDateTime.now().plusDays(365));
        int insert = zxChooseCourseMapper.insert(chooseCourse);
        if (insert <= 0) {
            ZhiXueException.cast("添加选课记录失败");
        }
        return chooseCourse;
    }




    /**
     * 查询学习资格
     * @param userId
     * @param courseId
     * @return
     */
    //返回  [{"code":"702001","desc":"正常学习"},{"code":"702002","desc":"没有选课或选课后没有支付"},{"code":"702003","desc":"已过期需要申请续期或重新支付"}]
    @Override
    public ZxCourseTablesDto getLearningStatus(String userId, Long courseId) {
        ZxCourseTablesDto courseTablesDto=new ZxCourseTablesDto();
        // 1. 查询我的课程表中这个课程
        ZxCourseTables zxCourseTables = getZxCourseTables(userId, courseId);
        // 2. 未查到，返回一个状态码为"702002"的对象
        if(zxCourseTables==null){
             courseTablesDto=new ZxCourseTablesDto();
             courseTablesDto.setLearnStatus("702002");
             return courseTablesDto;
        }
        // 3. 查到了，判断是否过期
        boolean isExpires = LocalDateTime.now().isAfter(zxCourseTables.getValidtimeEnd());
        // 3.1 已过期，返回状态码为"702003"的对象
        if (isExpires) {
            BeanUtils.copyProperties(zxCourseTables, courseTablesDto);
            courseTablesDto.setLearnStatus("702003");
            return courseTablesDto;
        }
        // 3.2 未过期，返回状态码为"702001"的对象
        else {
            BeanUtils.copyProperties(zxCourseTables, courseTablesDto);
            courseTablesDto.setLearnStatus("702001");
            return courseTablesDto;
        }
    }


    /**
     * 我的课程表
     * @param params
     * @return
     */
    @Override
    public PageResult<ZxCourseTables> myCourseTables(MyCourseTableParams params) {
        return null;
    }


    @Override
    public boolean saveChooseCourseStatus(String chooseCourseId) {
        // 1.根据选课id，查询选课表
        ZxChooseCourse chooseCourse = zxChooseCourseMapper.selectById(chooseCourseId);
        if (chooseCourse == null) {
            log.error("接收到购买课程的消息，根据选课id未查询到课程，选课id：{}", chooseCourseId);
            return false;
        }
        // 2.选课状态为未支付时，更新选课状态为选课成功
        if ("701002".equals(chooseCourse.getStatus())) {
            chooseCourse.setStatus("701001");
            int update = zxChooseCourseMapper.updateById(chooseCourse);
            if (update <= 0) {
                log.error("更新选课记录失败：{}", chooseCourse);
            }
        }
        // 3.向我的课程表添加记录
        addCourseTables(chooseCourse);
        return true;
    }


}
